home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 15
/
CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso
/
CUCD
/
Graphics
/
MysticView
/
source
/
MysticView.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-12-28
|
29KB
|
1,239 lines
/*********************************************************************
----------------------------------------------------------------------
$VER: MysticView.c 0.68
by Captain Bifat
© 1996 TEK neoscientists
simple Workbench DataType Picture Viewer
using render.library
- appwindow reference: AmigaMail AppWindow.c
- picture datatype reference: Cloanto ViewDT.c
------------------------------------------------------ tabsize = 4 ---
*********************************************************************/
#include <stdio.h>
#include <string.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <render/render.h>
#include <render/renderhooks.h>
#include <libraries/gadtools.h>
#include <utility/hooks.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/wb.h>
#include <proto/dos.h>
#include <proto/render.h>
#include <proto/gadtools.h>
#include <proto/asl.h>
#include "global.h"
#include "loaddtpicture.h"
#include "guigfx.h"
#include "Logo.h"
#include "wbview.h"
/*------------------------------------------------------------------*/
#define ID_APPWIN 0x123
#define UDATA_APPWIN 0x777
#define POOLPUDSIZE 10000
#define RGBWEIGHT 0x080808
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define INFOTEXT_LOADED "%s (%s)"
#define INFOTEXT_LOAD_ERROR "(%s - Error)"
#define INFOTEXT_NO_DATATYPE "(%s - Unknown)"
/*------------------------------------------------------------------*/
enum MITEMS { MITEM_NOHIGHLIGHT=1,
MITEM_OPEN,MITEM_ABOUT,MITEM_QUIT,
MITEM_GREEDY,MITEM_ECONOMICAL,MITEM_SPARINGLY,MITEM_PASSIVE,
MITEM_HAM_FAST,MITEM_HAM_BEST,MITEM_HAM_MEDIUM
};
/*
* Note: MITEM_NOHIGHLIGHT is a special constant that defines a
* menu entry's highlighting type to be set to HIGHNONE later.
*/
struct NewMenu mainmenu[] =
{
{NM_TITLE, "Project", 0, 0, 0, 0},
{NM_ITEM, "Open Picture...", "O", 0, 0, (APTR) MITEM_OPEN},
{NM_ITEM, NM_BARLABEL, 0, 0, 0, 0},
{NM_ITEM, "About MysticView...", 0, 0, 0, (APTR) MITEM_ABOUT},
{NM_ITEM, NM_BARLABEL, 0, 0, 0, 0},
{NM_ITEM, "Quit", "Q", 0, 0, (APTR) MITEM_QUIT},
{NM_TITLE, "Settings", 0, 0, 0, 0},
{NM_ITEM, "Share Screen Pens...", 0, 0, 0, (APTR) MITEM_NOHIGHLIGHT},
{NM_ITEM, "Greedy", 0, CHECKIT, 4+8+16, (APTR) MITEM_GREEDY},
{NM_ITEM, "Economical", 0, CHECKIT, 2+8+16, (APTR) MITEM_ECONOMICAL},
{NM_ITEM, "Sparingly", 0, CHECKIT, 2+4+16, (APTR) MITEM_SPARINGLY},
{NM_ITEM, "Passive", 0, CHECKIT, 2+4+8, (APTR) MITEM_PASSIVE},
{NM_ITEM, NM_BARLABEL, 0, 0, 0, 0},
{NM_ITEM, "HAM Remapping...", 0, 0, 0, (APTR) MITEM_NOHIGHLIGHT},
{NM_ITEM, "Fast", 0, CHECKIT, 256+512, (APTR) MITEM_HAM_FAST},
{NM_ITEM, "Medium", 0, CHECKIT, 128+512, (APTR) MITEM_HAM_MEDIUM},
{NM_ITEM, "Good", 0, CHECKIT, 128+256, (APTR) MITEM_HAM_BEST},
/* {NM_ITEM, NM_BARLABEL, 0, 0, 0, 0},
{NM_ITEM, "Best Refresh for...", 0, 0, 0, (APTR) MITEM_NOHIGHLIGHT},
{NM_ITEM, "Slow Graphics", 0, CHECKIT, 8192+16384, 0},
{NM_ITEM, "Fast Graphics", 0, CHECKIT, 4096+16384, 0},
{NM_ITEM, "Low Memory", 0, CHECKIT, 4096+8192, 0},
{NM_ITEM, NM_BARLABEL, 0, 0, 0, 0},
{NM_ITEM, "Aspect Ratio...", 0, 0, 0, (APTR) MITEM_NOHIGHLIGHT},
{NM_ITEM, "Keep", 0, CHECKIT, 262144+524288, 0},
{NM_ITEM, "Ignore Picture", 0, CHECKIT, 131072+524288, 0},
{NM_ITEM, "Ignore Screen", 0, CHECKIT, 131072+262144, 0},
*/
{NM_END, NULL, 0, 0, 0, 0,}
};
/*------------------------------------------------------------------*/
/*********************************************************************
----------------------------------------------------------------------
ToggleMenuFlags(menu,identifier,setmask,clearmask)
----------------------------------------------------------------------
*********************************************************************/
void ToggleMenuFlags(struct Menu *menu, ULONG id, UWORD set, UWORD clear)
{
do
{
struct MenuItem *mi = menu->FirstItem;
do
{
if (GTMENUITEM_USERDATA(mi) == (APTR)id)
{
mi->Flags &= ~clear;
mi->Flags |= set;
}
} while (mi = mi->NextItem);
} while (menu = menu->NextMenu);
}
/*********************************************************************
----------------------------------------------------------------------
GetMenuFlag(menu,identifier,mask)
----------------------------------------------------------------------
*********************************************************************/
ULONG GetMenuFlag(struct Menu *menu, ULONG id)
{
do
{
struct MenuItem *mi = menu->FirstItem;
do
{
if (GTMENUITEM_USERDATA(mi) == (APTR)id)
{
return ((mi->Flags & CHECKED) ? id : NULL);
}
} while (mi = mi->NextItem);
} while (menu = menu->NextMenu);
}
/*********************************************************************
----------------------------------------------------------------------
GetMenuSettings (wbview)
get the current settings from the menus.
----------------------------------------------------------------------
*********************************************************************/
void GetMenuSettings(struct WBView *wbv)
{
wbv->settings.pensharing = GetMenuFlag(wbv->menu, MITEM_GREEDY) +
GetMenuFlag(wbv->menu, MITEM_ECONOMICAL) +
GetMenuFlag(wbv->menu, MITEM_SPARINGLY) +
GetMenuFlag(wbv->menu, MITEM_PASSIVE);
wbv->settings.remapping = GetMenuFlag(wbv->menu, MITEM_HAM_FAST) +
GetMenuFlag(wbv->menu, MITEM_HAM_BEST) +
GetMenuFlag(wbv->menu, MITEM_HAM_MEDIUM);
}
/*********************************************************************
----------------------------------------------------------------------
SetMenuSettings (wbview)
put the current settings into the menus.
----------------------------------------------------------------------
*********************************************************************/
void SetMenuSettings(struct WBView *wbv)
{
#define CLEARITEM(a) ToggleMenuFlags(wbv->menu,a,NULL,CHECKED);
#define SETITEM(a) ToggleMenuFlags(wbv->menu,a,CHECKED,NULL);
ClearMenuStrip(wbv->window);
CLEARITEM(MITEM_GREEDY);
CLEARITEM(MITEM_ECONOMICAL);
CLEARITEM(MITEM_SPARINGLY);
CLEARITEM(MITEM_PASSIVE);
SETITEM(wbv->settings.pensharing);
CLEARITEM(MITEM_HAM_FAST);
CLEARITEM(MITEM_HAM_MEDIUM);
CLEARITEM(MITEM_HAM_BEST);
SETITEM(wbv->settings.remapping);
ResetMenuStrip(wbv->window, wbv->menu);
#undef SETITEM
#undef CLEARITEM
}
/*********************************************************************
----------------------------------------------------------------------
FileRequest(req, title, pathname, filename)
----------------------------------------------------------------------
*********************************************************************/
BOOL FileRequest(struct FileRequester *fr,STRPTR title,STRPTR pathname,STRPTR filename)
{
BOOL result;
if(result = AslRequestTags(fr,ASLFR_TitleText,title,
ASLFR_InitialFile,filename,
ASLFR_InitialDrawer,pathname,
TAG_DONE))
{
if(strlen(fr->fr_File) < FILENAMESIZE)
{
if(strlen(fr->fr_Drawer) < PATHNAMESIZE)
{
strcpy(pathname,fr->fr_Drawer);
strcpy(filename,fr->fr_File);
}
else
{
result = FALSE;
}
}
else
{
result = FALSE;
}
}
return result;
}
/*********************************************************************
----------------------------------------------------------------------
ProgressFunc()
Progress function to be called when rendering HAM pictures.
----------------------------------------------------------------------
*********************************************************************/
ULONG __asm __saveds ProgressFunc( register __a0 struct Hook *hook,
register __a2 APTR histogram,
register __a1 struct RND_ProgressMessage *message )
{
static char text[100];
static WORD oldproz = -1, proz;
struct WBView *wbv = (struct WBView *) hook->h_Data;
proz = (message->RND_PMsg_count * 100 / message->RND_PMsg_total) & ~0x3;
if(proz != oldproz)
{
oldproz = proz;
switch(message->RND_PMsg_type)
{
case PMSGTYPE_LINES_ADDED:
sprintf(text,"Histogram: %d%%",proz);
break;
case PMSGTYPE_COLORS_CHOSEN:
sprintf(text,"Palette: %d%%",proz);
break;
case PMSGTYPE_LINES_RENDERED:
sprintf(text,"Rendering: %d%%",proz);
break;
case PMSGTYPE_LINES_CONVERTED:
sprintf(text,"Converting: %d%%",proz);
break;
}
SetWindowTitles( wbv->window, text, (UBYTE *) ~0 );
}
return TRUE;
}
/*********************************************************************
----------------------------------------------------------------------
About(window)
----------------------------------------------------------------------
*********************************************************************/
void About(struct Window *win)
{
static struct EasyStruct req =
{
sizeof(struct EasyStruct),0,
"About...",
PROGNAME "\n"
"© 1996 by TEK neoscientists.\n\n"
"Written by Captain Bifat,\n"
"logo drawn by Banshee\n"
"and Captain Bifat.\n\n"
"MysticView is freeware.\n"
"It's mainly intended to act as\n"
"an example for the power of\n"
"render.library.",
"Okay"
};
EasyRequest(win,&req,NULL);
}
/*********************************************************************
----------------------------------------------------------------------
success = RemapHAM(wbv,chunkyimage, progresshook)
remap a HAM image to 256 colors.
----------------------------------------------------------------------
*********************************************************************/
BOOL RemapHAM(struct WBView *wbv, struct ChunkyImage *ci, struct Hook *progresshook)
{
ULONG *rgb;
BOOL success = FALSE;
ULONG histotype = HSTYPE_15BIT_TURBO;
ULONG numcolors = 256;
ULONG interleave = 2;
GetMenuSettings(wbv);
switch (wbv->settings.remapping)
{
case MITEM_HAM_FAST:
histotype = HSTYPE_12BIT_TURBO;
numcolors = 256;
interleave = 3;
break;
case MITEM_HAM_MEDIUM:
histotype = HSTYPE_15BIT_TURBO;
numcolors = 256;
interleave = 2;
break;
case MITEM_HAM_BEST:
histotype = HSTYPE_18BIT_TURBO;
numcolors = 256;
interleave = 2;
break;
}
/*
* If in HAM mode, the picture has to be re-rendered
* completely. This is trivial with render.library.
* First, allocate RGB buffer and create a histogram.
*/
if(rgb=AllocVecPooled(ci->width * ci->height * sizeof(ULONG)))
{
APTR histo;
if(histo = CreateHistogram( RND_HSType, histotype, TAG_DONE))
{
/*
* convert chunky array to RGB,
* then add it to the histogram
*/
Chunky2RGB(ci->chunky, ci->width, ci->height, rgb, ci->palette,
RND_ColorMode, ci->colormode,
RND_ProgressHook, progresshook,
TAG_DONE);
/*
* we use a trick here:
* The histogram is built over every <interleave> raster line.
*/
if(AddRGBImage(histo, rgb, ci->width, ci->height/interleave,
RND_SourceWidth,ci->width*interleave,
RND_ProgressHook,progresshook,
TAG_DONE) == ADDH_SUCCESS)
{
/*
* Extract palette out of the histogram, then render.
*/
if(ExtractPalette(histo, ci->palette, numcolors,
RND_ProgressHook,progresshook,TAG_DONE) == EXTP_SUCCESS)
{
if (Render(rgb, ci->width, ci->height, ci->chunky, ci->palette,
RND_ProgressHook,progresshook,TAG_DONE) == REND_SUCCESS)
{
success = TRUE;
}
FlushPalette(ci->palette);
}
}
DeleteHistogram(histo);
}
FreeVecPooled(rgb);
}
return success;
}
/*********************************************************************
----------------------------------------------------------------------
FreeLogo(wbv)
----------------------------------------------------------------------
*********************************************************************/
void FreeLogo(struct WBView *wbv)
{
if(wbv->logopalette)
{
DeletePalette(wbv->logopalette);
wbv->logopalette = NULL;
}
if(wbv->logopic)
{
FreeVecPooled(wbv->logopic);
wbv->logopic = NULL;
}
}
/*********************************************************************
----------------------------------------------------------------------
BOOL InitLogo(wbv)
----------------------------------------------------------------------
*********************************************************************/
BOOL InitLogo(struct WBView *wbv)
{
if(wbv->logopic == NULL)
{
if(!(wbv->logopic = AllocVecPooled(LOGOWIDTH*LOGOHEIGHT)))
{
return FALSE;
}
}
if(wbv->logopalette == NULL)
{
if(!(wbv->logopalette = CreatePalette(RND_HSType,HSTYPE_15BIT,TAG_DONE)))
{
return FALSE;
}
}
CopyMemQuick(Logo,wbv->logopic,LOGOWIDTH*LOGOHEIGHT);
ImportPalette(wbv->logopalette,LogoPalette,LOGOCOLORS,NULL);
wbv->logo.chunky = wbv->logopic;
wbv->logo.palette = wbv->logopalette;
wbv->logo.width = LOGOWIDTH;
wbv->logo.bytewidth = ((LOGOWIDTH+15)>>4)<<1;
wbv->logo.height = LOGOHEIGHT;
wbv->logo.aspect = 1;
wbv->logo.aspectmode = ASPM_KEEP_ALL;
}
/*********************************************************************
----------------------------------------------------------------------
DOUBLE GetScreenAspect(screen)
----------------------------------------------------------------------
*********************************************************************/
DOUBLE GetScreenAspect(struct Screen *screen)
{
ULONG modeID;
if ((modeID = GetVPModeID(&screen->ViewPort)) != INVALID_ID)
{
DisplayInfoHandle dih;
if(dih = FindDisplayInfo(modeID))
{
struct DisplayInfo di;
if(GetDisplayInfoData(dih,(UBYTE*)&di, sizeof(struct DisplayInfo),DTAG_DISP,modeID))
{
return (DOUBLE) di.Resolution.x / (DOUBLE) di.Resolution.y;
}
}
}
return 1;
}
/*********************************************************************
----------------------------------------------------------------------
FreeDisplayEntity (displayentity)
----------------------------------------------------------------------
*********************************************************************/
void FreeDisplayEntity (struct DisplayEntity *di)
{
if(di->psm)
{
DeletePenShareMap(di->psm);
di->psm = NULL;
}
di->converted = FALSE;
}
/*********************************************************************
----------------------------------------------------------------------
BOOL Display(wbview)
----------------------------------------------------------------------
*********************************************************************/
BOOL Display(struct WBView *wbv)
{
ULONG winwidth,winheight,width,height,x,y,centerleft,centertop;
DOUBLE picaspect,winaspect;
UBYTE *buf;
ULONG bufwidth;
struct DisplayEntity *di = &wbv->disp;
struct Window *window = wbv->window;
struct ChunkyImage *ci = di->ci;
x = window->BorderLeft;
y = window->BorderTop;
winwidth = window->Width - window->BorderRight - x;
winheight = window->Height - window->BorderBottom - y;
/*
* calculate dimensions
*/
width = winwidth;
if(ci->aspectmode == ASPM_NO_CARE)
{
height = winheight;
}
else
{
picaspect = (ci->aspectmode & ASPM_KEEP_PIC) ? ci->aspect : 1;
winaspect = (ci->aspectmode & ASPM_KEEP_SCREEN) ? wbv->aspect : 1;
if ( (DOUBLE) winheight > (DOUBLE) width * winaspect )
{
height = (DOUBLE) width / (DOUBLE) ci->width * (DOUBLE) ci->height * winaspect / picaspect;
height = MIN(height,winheight);
width = (DOUBLE) height / (DOUBLE) ci->height * (DOUBLE) ci->width * picaspect / winaspect;
}
else
{
width = (DOUBLE) winheight / (DOUBLE) ci->height * (DOUBLE) ci->width * picaspect / winaspect;
width = MIN(width,winwidth);
height = (DOUBLE) width / (DOUBLE) ci->width * (DOUBLE) ci->height * winaspect / picaspect;
}
}
bufwidth = (width + 15) & ~0xf;
centerleft = (winwidth-width)/2;
centertop = (winheight-height)/2;
/*
* obtain colors
*/
if(di->psm == NULL)
{
if (!(di->psm = CreatePenShareMap()))
{
FreeDisplayEntity(di);
return FALSE;
}
if (AddChunkyImage(di->psm->histogram,ci->chunky,
ci->width,ci->height,ci->palette,NULL) == ADDH_SUCCESS)
{
ULONG precision = PRECISION_IMAGE;
RectFill(window->RPort,x,y,x+winwidth-1,y+winheight-1);
GetMenuSettings(wbv);
switch (wbv->settings.pensharing)
{
case MITEM_GREEDY:
precision = PRECISION_EXACT;
break;
case MITEM_ECONOMICAL:
precision = PRECISION_IMAGE;
break;
case MITEM_SPARINGLY:
precision = PRECISION_ICON;
break;
case MITEM_PASSIVE:
precision = PRECISION_GUI;
break;
}
if (!(ObtainPenShareMap(di->psm,window->WScreen->ViewPort.ColorMap,precision)))
{
FreeDisplayEntity(di);
return FALSE;
}
}
else
{
FreeDisplayEntity(di);
return FALSE;
}
}
/*
* remap chunky image to screen pens
*/
if(di->converted == FALSE)
{
RemapChunkyArray(ci->chunky,ci->palette,
ci->width,ci->height,ci->chunky,di->psm);
di->converted = TRUE;
}
/*
* scale chunky image to the calculated dimensions,
* then dash it into the rastport
*/
if (buf = AllocVecPooled(bufwidth*height))
{
APTR scaleengine;
if (scaleengine = CreateScaleEngine(ci->width,ci->height,width,height,NULL))
{
Scale(scaleengine,ci->chunky,buf,RND_DestWidth,bufwidth,TAG_DONE);
DeleteScaleEngine(scaleengine);
DrawChunkyArray(window->RPort,buf,x+centerleft,y+centertop,width,height);
/*
* restore the background around the image
*/
if(centertop)
{
RectFill(window->RPort,x,y,x+winwidth-1,y+centertop-1);
RectFill(window->RPort,x,y+centertop+height,x+winwidth-1,y+winheight-1);
}
if(centerleft)
{
RectFill(window->RPort,x,y+centertop,x+centerleft-1,y+centertop+height-1);
RectFill(window->RPort,x+centerleft+width,y+centertop,x+winwidth-1,y+centertop+height-1);
}
FreeVecPooled(buf);
return TRUE;
}
}
return FALSE;
}
/*********************************************************************
----------------------------------------------------------------------
FreeChunkyImage (chunkyimage)
----------------------------------------------------------------------
*********************************************************************/
void FreeChunkyImage(struct ChunkyImage *ci)
{
if(ci->palette)
{
DeletePalette(ci->palette);
ci->palette = NULL;
}
if(ci->chunky)
{
FreeVecPooled(ci->chunky);
ci->chunky = NULL;
}
}
/*********************************************************************
----------------------------------------------------------------------
DeleteWBView (wbview)
----------------------------------------------------------------------
*********************************************************************/
void DeleteWBView(struct WBView *wbv)
{
if(wbv)
{
if(wbv->menu)
{
ClearMenuStrip(wbv->window);
}
if(wbv->freq)
{
FreeAslRequest(wbv->freq);
wbv->freq=NULL;
}
FreeLogo(wbv);
FreeDisplayEntity(&wbv->disp);
FreeChunkyImage(&wbv->chunkypic);
if(wbv->appwindow)
{
RemoveAppWindow(wbv->appwindow);
wbv->appwindow = NULL;
}
if(wbv->window)
{
CloseWindow(wbv->window);
wbv->window = NULL;
}
if(wbv->menu)
{
FreeMenus(wbv->menu);
wbv->menu = NULL;
}
if(wbv->appmsgport)
{
DeleteMsgPort(wbv->appmsgport);
wbv->appmsgport = NULL;
}
FreeVecPooled(wbv);
}
}
/*********************************************************************
----------------------------------------------------------------------
wbview = CreateWBView (void)
----------------------------------------------------------------------
*********************************************************************/
struct WBView *CreateWBView (void)
{
struct WBView *wbv;
BOOL success = FALSE;
if (wbv = AllocVecPooled(sizeof(struct WBView)))
{
memset(wbv,0,sizeof(struct WBView));
if(wbv->appmsgport = CreateMsgPort())
{
if (wbv->pubscreen = LockPubScreen(NULL))
{
wbv->aspect = GetScreenAspect(wbv->pubscreen);
if (wbv->menu = CreateMenus(mainmenu, TAG_DONE))
{
ToggleMenuFlags(wbv->menu,MITEM_NOHIGHLIGHT,HIGHNONE,NULL);
if(wbv->window = OpenWindowTags(NULL,
WA_Width,DEFAULT_WINWIDTH, WA_Height,DEFAULT_WINHEIGHT,
WA_MinWidth,MIN_WINWIDTH, WA_MinHeight,MIN_WINHEIGHT,
WA_MaxWidth,-1, WA_MaxHeight,-1,
WA_PubScreen,wbv->pubscreen, WA_Title,PROGNAME,
WA_NewLookMenus, TRUE,
WA_Flags,WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_SIZEGADGET |
WFLG_DEPTHGADGET | WFLG_SIZEBBOTTOM |
WFLG_SIMPLE_REFRESH,
WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE | IDCMP_MENUPICK | IDCMP_REFRESHWINDOW,
TAG_DONE))
{
APTR visinfo;
if (visinfo = GetVisualInfo(wbv->pubscreen, TAG_DONE))
{
if(LayoutMenus(wbv->menu, visinfo, GTMN_NewLookMenus,TRUE,TAG_DONE))
{
if(wbv->appwindow = AddAppWindow(ID_APPWIN,UDATA_APPWIN,
wbv->window,wbv->appmsgport,NULL))
{
if (InitLogo(wbv))
{
if(wbv->freq = AllocAslRequestTags(ASL_FileRequest,
ASLFR_Window,wbv->window,
ASLFR_SleepWindow,TRUE,
ASLFR_RejectIcons,TRUE,
TAG_DONE))
{
success = TRUE;
}
}
}
}
FreeVisualInfo(visinfo);
}
}
}
UnlockPubScreen(NULL,wbv->pubscreen);
}
}
}
if(success == TRUE)
{
/*
* settings
*/
wbv->settings.pensharing = DEFAULT_PENSHARING;
wbv->settings.remapping = DEFAULT_REMAPPING;
/*
* do some more initializations
*/
SetMenuStrip(wbv->window, wbv->menu);
SetABPenDrMd(wbv->window->RPort,1,0,JAM2);
SetMenuSettings(wbv);
wbv->ProgressHook.h_Data = wbv;
wbv->ProgressHook.h_Entry = (ULONG (*)()) ProgressFunc;
wbv->disp.ci = &wbv->logo;
Display(wbv);
}
else
{
/*
* failure - close down gently
*/
DeleteWBView(wbv);
wbv = NULL;
}
return wbv;
}
/*********************************************************************
----------------------------------------------------------------------
BOOL LoadPicture (wbv,chunkyimage,filename,renderhook)
----------------------------------------------------------------------
*********************************************************************/
BOOL LoadPicture(struct WBView *wbv, struct ChunkyImage *ci, STRPTR filename, struct Hook *renderhook)
{
struct Picture pic;
BOOL success = FALSE;
/*
* get DT picture. Remember to use a BMF_STANDARD BitMap,
* because we want to convert it via Planar2Chunky()!
*/
if(!GetDataTypesPicture(filename,&pic,BMF_STANDARD))
{
ULONG chunkysize = pic.bmap->BytesPerRow * 8 * pic.bmap->Rows;
/*
* Allocate buffers for chunky image and palette
*/
if(ci->chunky = AllocVecPooled(chunkysize))
{
UWORD histotype = HSTYPE_15BIT_TURBO;
GetMenuSettings(wbv);
if(wbv->settings.remapping == MITEM_HAM_BEST)
{
histotype = HSTYPE_18BIT_TURBO;
}
if(ci->palette = CreatePalette(RND_HSType,histotype,TAG_DONE))
{
ULONG ax,ay;
/*
* fill in parameters
*/
ci->width = pic.bmhd.bmh_Width;
ci->bytewidth = pic.bmap->BytesPerRow;
ci->height = pic.bmap->Rows;
ci->displayID = pic.display_ID;
ax = pic.bmhd.bmh_XAspect;
ay = pic.bmhd.bmh_YAspect;
ax = !ax ? 1 : ax;
ay = !ay ? 1 : ay;
ci->aspect = (DOUBLE) ax / (DOUBLE) ay;
ci->aspectmode = ASPM_KEEP_ALL;
if(ci->displayID & HAM)
{
ci->colormode = (pic.bmap->Depth == 8 ? COLORMODE_HAM8 : COLORMODE_HAM6);
}
else
{
ci->colormode = COLORMODE_CLUT;
}
/*
* convert BitMap's bitplanes to chunky bytes
*/
Planar2Chunky( pic.bmap->Planes,ci->bytewidth,
pic.bmap->Rows,pic.bmap->Depth,
ci->bytewidth,ci->chunky,
RND_DestWidth,ci->width,TAG_DONE );
/*
* import image palette
*/
ImportPalette(ci->palette, &pic.palette[1], pic.palette_entries,
RND_PaletteFormat, PALFMT_RGB32,
RND_EHBPalette, ((ci->displayID & EXTRA_HALFBRITE) ? TRUE : FALSE),
RND_NewPalette,TRUE,
TAG_DONE);
/*
* process HAM images
*/
if(ci->displayID & HAM)
{
success = RemapHAM(wbv,ci,renderhook);
}
else
{
success = TRUE;
}
}
}
if(success == FALSE)
{
FreeChunkyImage(ci);
}
/*
* (hopefully) we've got what we want, anyway
* the datatype picture is no longer needed
*/
FreePicture(&pic);
}
return success;
}
/*********************************************************************
----------------------------------------------------------------------
BOOL ShowPicture(wbview,pathname,filename)
----------------------------------------------------------------------
*********************************************************************/
BOOL ShowPicture(struct WBView *wbv, STRPTR pathname, STRPTR filename)
{
char formatname[FORMATNAMESIZE];
char *infotext;
char fullname[FILENAMESIZE+PATHNAMESIZE];
BOOL success = FALSE;
infotext = "";
strcpy(fullname,pathname);
if (AddPart(fullname,filename,FILENAMESIZE+PATHNAMESIZE))
{
if (IsDataTypes(fullname, formatname, FORMATNAMESIZE-1))
{
FreeChunkyImage(&wbv->chunkypic);
FreeDisplayEntity(&wbv->disp);
if(LoadPicture(wbv, &wbv->chunkypic,fullname,&wbv->ProgressHook))
{
wbv->disp.ci = &wbv->chunkypic;
infotext = INFOTEXT_LOADED;
success = TRUE;
}
else
{
InitLogo(wbv);
wbv->disp.ci = &wbv->logo;
infotext = INFOTEXT_LOAD_ERROR;
}
Display(wbv);
}
else
{
infotext = INFOTEXT_NO_DATATYPE;
}
}
sprintf(wbv->windowtitle,infotext,filename,formatname);
SetWindowTitles( wbv->window, wbv->windowtitle, (UBYTE *) ~0 );
return success;
}
/*********************************************************************
----------------------------------------------------------------------
HandleWBView (wbview)
----------------------------------------------------------------------
*********************************************************************/
void HandleWBView(struct WBView *wbv)
{
BOOL finish = FALSE;
ULONG idcmpSignal = 1L << wbv->window->UserPort->mp_SigBit;
ULONG appSignal = 1L << wbv->appmsgport->mp_SigBit;
char pathname[PATHNAMESIZE], filename[FILENAMESIZE];
do
{
struct IntuiMessage *imsg;
struct AppMessage *appmsg;
BOOL foundpic;
Wait(idcmpSignal | appSignal);
while (imsg = (struct IntuiMessage *) GetMsg(wbv->window->UserPort))
{
ULONG iclass = imsg->Class;
ULONG icode = imsg->Code;
ReplyMsg((struct Message *) imsg);
switch (iclass)
{
case CLOSEWINDOW:
finish = TRUE;
break;
case NEWSIZE:
Display(wbv);
RefreshWindowFrame(wbv->window);
break;
case REFRESHWINDOW:
BeginRefresh(wbv->window);
Display(wbv);
EndRefresh(wbv->window,TRUE);
break;
case MENUPICK:
while((icode != MENUNULL) && (finish == FALSE))
{
struct MenuItem *item = ItemAddress(wbv->menu, icode);
ULONG code = (ULONG) MENU_USERDATA(item);
switch (code)
{
case MITEM_OPEN:
if (FileRequest(wbv->freq, "Load Picture", wbv->pathname, wbv->filename))
{
Display(wbv); /* refresh once again */
ShowPicture(wbv,wbv->pathname,wbv->filename);
}
break;
case MITEM_ABOUT:
About(wbv->window);
break;
case MITEM_QUIT:
finish = TRUE;
break;
}
icode = item->NextSelect;
}
break;
}
}
foundpic = FALSE;
while (appmsg = (struct AppMessage *) GetMsg(wbv->appmsgport))
{
int i;
struct WBArg *argptr = appmsg->am_ArgList;
for (i = 0; i < appmsg->am_NumArgs && foundpic == FALSE; i++)
{
if (NameFromLock(argptr->wa_Lock,pathname,PATHNAMESIZE))
{
if(strlen(argptr->wa_Name))
{
strcpy(filename,argptr->wa_Name);
foundpic = TRUE;
}
}
argptr++; /* point to next argument */
}
ReplyMsg((struct Message *) appmsg);
}
if(foundpic == TRUE)
{
/*
* we've found something. Maybe it's a
* valid datatype picture class file?
* We find out by trying.
*/
strcpy(wbv->pathname,pathname);
strcpy(wbv->filename,filename);
ShowPicture(wbv,pathname,filename);
}
} while (finish == FALSE);
}
/*********************************************************************
----------------------------------------------------------------------
main
----------------------------------------------------------------------
*********************************************************************/
void main (void)
{
if(InitGlobal())
{
struct WBView *viewer;
if (viewer = CreateWBView())
{
HandleWBView(viewer);
DeleteWBView(viewer);
}
CloseGlobal();
}
}